home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / mnsbm.zip / DIR.CB next >
Text File  |  1989-10-31  |  25KB  |  909 lines

  1. /*                                                                                                  */
  2. /*     dir.m:                                                                                     */
  3. /*         A full-fledged, integrated environment for manipulating files         */
  4. /*     and directories from within BRIEF.    Uses the dialog manager.             */
  5. /*     If sorting is desired, also pulls in sort macros.                             */
  6. /*                                                                                                  */
  7. /*         Written by Dan Teven.  Preliminary version, August 6, 1987.          */
  8. /*     Requires the dialog manager from BRIEF version 2.01.                         */
  9. /*                                                                                                  */
  10.  
  11. #include "dialog.h"
  12.  
  13. /*     These definitions are the names of temporary files that the directory */
  14. /*     macro will use.  You can change them to specify a full path name.      */
  15. /*     For best performance, specify a temp file on a RAMdisk.                     */
  16.  
  17. #define TEMP_FILE       "dir.tmp"
  18. #define ERROR_FILE      "dir.err"
  19.  
  20. #define TAG_CHAR          "√"
  21.  
  22. /*     These numbers define the column positions for the various fields         */
  23. /*     of the directory listing (with the format defined here and no tabs).  */
  24. /*     The full definition is a sort command for the buffer.                      */
  25.  
  26. #define NAME_SORT   "_dir_sort"
  27. #define EXT_SORT      "_dir_sort 11"
  28. #define SIZE_SORT   "_dir_sort 15"
  29. #define TIME_SORT   "_dir_sort 25"
  30.  
  31. /*     The tag column is with tabs 6.                                                     */
  32.  
  33. #define TAG_COL      47
  34.  
  35. /*                                                                                                  */
  36. /*     _init:                                                                                     */
  37. /*         Initialize global variables.    The only two global strings are         */
  38. /*     used to hold the current directory path and file spec.                     */
  39. /*                                                                                                  */
  40.  
  41. _init ()
  42. {
  43.     int _dir_buffer,
  44.          _dir_tags;
  45.        string _dir_wd,
  46.              _filespec;
  47.  
  48.     global _dir_wd,
  49.              _filespec,
  50.              _dir_buffer,
  51.              _dir_tags;
  52.  
  53. }
  54.  
  55. /*                                                                                                  */
  56. /*     dir:                                                                                         */
  57. /*         The directory macro.  The syntax is dir [pathspec] where              */
  58. /*     pathspec is an optional alternate path or file specifier to              */
  59. /*     use.                                                                                         */
  60. /*                                                                                                  */
  61.  
  62. dir (...)
  63. {
  64.     extern add_to_path;
  65.  
  66.     int last_loc,
  67.          current_buffer;
  68.  
  69.     string initial_wd;
  70.  
  71.     /*     Get the current directory so we can change back to it upon             */
  72.     /*     exiting.  Make that the default.                                              */
  73.  
  74.     getwd ("", initial_wd);
  75.     _dir_wd = initial_wd;
  76.  
  77.     /*     If no directory spec passed on the command line, we use                 */
  78.     /*     the default.  We use the passed spec if possible.                         */
  79.  
  80.     if (!get_parm (0, _filespec))
  81.         _filespec = _dir_wd;
  82.  
  83.     /*     Try to change immediately to the filespec entered as if                 */
  84.     /*     it were a directory.  If we can change to it, it becomes              */
  85.     /*     the default for future invocations.                                          */
  86.  
  87.     if (cd (_filespec))
  88.         {
  89.         getwd ("", _dir_wd);
  90.         _filespec = "*.*";
  91.         }
  92.     else
  93.         /*     OK, so it wasn't just a directory.                                         */
  94.         /*     If we have a backslash in the path specifier, split it             */
  95.         /*     into a new directory specifier and file specifier.                  */
  96.         /*     If not, it must be all file specifier, which implies                 */
  97.         /*     use of the current directory.                                              */
  98.  
  99.         {
  100.         if (last_loc = search_string ("\\\\[~\\\\/]+", _filespec + "", TRUE))
  101.             {
  102.             _dir_wd = substr (_filespec, 1, last_loc - 1);
  103.             _filespec = substr (_filespec, last_loc + 1);
  104.             }
  105.  
  106.         /*     Try to change to the directory specified.  If the cd                 */
  107.         /*     fails, we know the directory is bad, and we reset it to             */
  108.         /*     the current directory and exit.                                             */
  109.  
  110.         if (cd (_dir_wd))
  111.             getwd ("", _dir_wd);
  112.         else
  113.             {
  114.             error ("Invalid path specified.");
  115.             beep ();
  116.             return FALSE;
  117.             }
  118.         }
  119.  
  120.     message ("Creating directory list...");
  121.  
  122.     /*     Create a temporary file containing the directory listing              */
  123.     /*     for _filespec, and read it in.  We are already in the                  */
  124.     /*     directory referred to.                                                             */
  125.  
  126.     current_buffer = inq_buffer ();
  127.     set_buffer (_dir_buffer = create_buffer ("Directory", NULL, TRUE));
  128.  
  129.     dos ("dir " + (_filespec + (" >&" + TEMP_FILE)));
  130.     read_file (TEMP_FILE);
  131.  
  132.     /*     Determine if any files matched the file spec.  If none did,          */
  133.     /*     we clean up and exit.                                                             */
  134.  
  135.     if (search_back ("<File not found", TRUE, TRUE))
  136.         {
  137.         error ("No files found.");
  138.         beep ();
  139.         }
  140.     else
  141.         {
  142.         _reformat_directory ();
  143.         _process_menu (4, 20, 54, 2, "", "Press Alt-H for Help", NULL, _dir_buffer, "_dir_action", TRUE);
  144.         }
  145.  
  146.     /*     Delete the directory buffer, and the file(s) associated with         */
  147.     /*     it.  Reset the packages for the current buffer.                          */
  148.  
  149.     set_buffer (current_buffer);
  150.     call_registered_macro (1);
  151.     delete_buffer (_dir_buffer);
  152.     del (TEMP_FILE);
  153.  
  154.     /*     Change back to the original directory, and return.                      */
  155.  
  156.     cd (initial_wd);
  157.     return TRUE;
  158. }
  159.  
  160. /*                                                                                                  */
  161. /*     _reformat_directory:                                                                  */
  162. /*         Takes a buffer (named by the global variable _dir_buffer) and         */
  163. /*     converts it to a more readable and useful menu-style format.             */
  164. /*                                                                                                  */
  165.  
  166. _reformat_directory ()
  167. {
  168.     string name;
  169.  
  170.     /*     Delete the first four lines of the file, which are two                 */
  171.     /*     blank lines, the volume label, and the directory specifier.          */
  172.  
  173.     move_abs (4, 1);
  174.     drop_anchor (3);
  175.     top_of_buffer ();
  176.     delete_block ();
  177.  
  178.     /*     Insert a tab before every remaining line of the file.  Then          */
  179.     /*     insert two delimiters into the file, and sort it so that              */
  180.     /*     all the directories are in one list and all the files are             */
  181.     /*     in the other.                                                                         */
  182.  
  183.     translate ("<{[~]*}>", "\\t\\0      ;_dir_tag_line", TRUE, TRUE);
  184.     insert ("Directories:\nFiles:\n");
  185.  
  186.     while (search_fwd ("<DIR>", FALSE, TRUE))
  187.         {
  188.         drop_anchor (3);
  189.         cut ();
  190.         search_back ("<F", TRUE, TRUE);
  191.         paste ();
  192.         }
  193.  
  194.     /*     Remove the <DIR> marker for the directories, which we                  */
  195.     /*     know are all before the current position at this point.                 */
  196.     /*     Also, change the action to _dir_chdir.                                      */
  197.  
  198.     translate ("<DIR>   ", "        ", TRUE, FALSE, TRUE, FALSE, FALSE);
  199.     translate (";_dir_tag_line", ";_dir_chdir", TRUE, FALSE, TRUE, FALSE, FALSE);
  200.  
  201.     /*     Delete the last lines of the buffer, which are the                      */
  202.     /*     number of files/free space and a blank line.                              */
  203.  
  204.     end_of_buffer ();
  205.     up ();
  206.     delete_line ();
  207.     delete_line ();
  208.  
  209.     tabs (6);
  210.     top_of_buffer ();
  211.     _dir_tags = 0;
  212. }
  213.  
  214. /*                                                                                                  */
  215. /*     _dir_action:                                                                             */
  216. /*         Handles events passed to it by the dialog manager.                      */
  217. /*                                                                                                  */
  218.  
  219. _dir_action (...)
  220. {
  221.     int event_type;
  222.  
  223.     string button_text;
  224.  
  225.     get_parm (0, event_type);
  226.  
  227.  
  228.     switch (event_type)
  229.         {
  230.         case DIALOG_INIT:
  231.             {
  232.             assign_to_key ("<Alt-A>", "_dir_tag_all");
  233.             assign_to_key ("<Alt-C>", "_dir_copy");
  234.             assign_to_key ("<Alt-D>", "_dir_delete");
  235.             assign_to_key ("<Alt-E>", "_for_tagged _dir_edit");
  236.             assign_to_key ("<Alt-H>", "_dir_help");
  237.             assign_to_key ("<Alt-N>", NAME_SORT);
  238.             assign_to_key ("<Alt-R>", "_for_tagged _dir_rename");
  239.             assign_to_key ("<Alt-S>", SIZE_SORT);
  240.             assign_to_key ("<Alt-T>", TIME_SORT);
  241.             assign_to_key ("<Alt-X>", EXT_SORT);
  242.             assign_to_key ("<Alt-Z>", "dos");
  243.  
  244.             button_text = "Directory of " + _dir_wd;
  245.  
  246.             /*     If the directory name is the root, we don't                         */
  247.             /*     add the \ before the file specifier.                                 */
  248.  
  249.             if (strlen (_dir_wd) > 3)
  250.                 button_text += "\\";
  251.             message (button_text + (_filespec + "."));
  252.             }
  253.         case DIALOG_TERM:
  254.             {
  255.             assign_to_key ("<Alt-A>", "nothing");
  256.             assign_to_key ("<Alt-C>", "nothing");
  257.             assign_to_key ("<Alt-D>", "nothing");
  258.             assign_to_key ("<Alt-E>", "nothing");
  259.             assign_to_key ("<Alt-H>", "nothing");
  260.             assign_to_key ("<Alt-N>", "nothing");
  261.             assign_to_key ("<Alt-R>", "nothing");
  262.             assign_to_key ("<Alt-S>", "nothing");
  263.             assign_to_key ("<Alt-T>", "nothing");
  264.             assign_to_key ("<Alt-X>", "nothing");
  265.             assign_to_key ("<Alt-Z>", "nothing");
  266.             }
  267.  
  268.             /*     We check to make sure there's a semicolon on the line          */
  269.             /*     before we move to it.                                                     */
  270.  
  271.         case DIALOG_ALTER_MENU:
  272.             {
  273.             get_parm (2, button_text);
  274.  
  275.             if (!index (button_text, ";"))
  276.                 return FALSE;
  277.             }
  278.  
  279.             /*     If a menu button is picked, we execute